package com.my.learn.nio.netty;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

import java.util.UUID;

public class MyServer {

    public static void main(String[] args) throws InterruptedException {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<Channel>() {

                                      @Override
                                      protected void initChannel(Channel channel) throws Exception {
                                          channel.pipeline()
                                                  .addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4))
                                                  .addLast(new LengthFieldPrepender(4))
                                                  .addLast(new StringDecoder(CharsetUtil.UTF_8))
                                                  .addLast(new StringEncoder(CharsetUtil.UTF_8))
                                                  .addLast(new SimpleChannelInboundHandler<String>() {

                                                      @Override
                                                      protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
                                                          Thread.sleep(2000);
                                                          System.out.println(ctx.channel().remoteAddress() + ":" + msg);
                                                          ctx.writeAndFlush("from server: " + UUID.randomUUID());
                                                      }

                                                      @Override
                                                      public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                                                          cause.printStackTrace();
                                                          ctx.close();
                                                      }
                                                  });
                                      }
                                  }
                    );
            ChannelFuture future = serverBootstrap.bind(9999).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully().sync();
            workerGroup.shutdownGracefully().sync();
        }
    }
}
